/*This file is part of Legend of the Dark Blade.

    Legend of the Dark Blade is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Legend of the Dark Blade is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser Public License for more details.

    You should have received a copy of the GNU Lesser Public License
    along with Legend of the Dark Blade.  If not, see <http://www.gnu.org/licenses/>.*/

//requires: SDL 2.1

#include <string>
using std::string;
#include <math.h>
#include <iostream>
#include <fstream>

using namespace std;

#include <SDL/SDL.h>

#include "global.h"

bool quit = false;
int iter = 0;
int cam_x = 0;
int cam_y = 0;
int spawn_x = 100;
int spawn_y = 100;
    Player p1;
    Map map;

//int map [MAPHEIGHT] [MAPWIDTH];

Uint8 *keystates = NULL;

SDL_Surface* screen = NULL;

SDL_Surface* BG = NULL;
SDL_Surface* HUD = NULL;
SDL_Surface* life = NULL;
SDL_Surface* power = NULL;

SDL_Surface* player = NULL;
SDL_Rect pclip[ 20 ];

SDL_Surface* tilesheet = NULL;
SDL_Rect clip[ 40 ];

SDL_Surface* orb = NULL;

bool circlecollide(int c1_x,int c1_y,int c1_radius,int c2_x,int c2_y,int c2_radius){
     int dx = c1_x - c2_x;
     int dy = c1_y - c2_y;
     int dist = c1_radius + c2_radius;

     if(dx * dx + dy * dy < dist * dist) return true;
     else return false;
}

bool boxcollide(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2 ){
     //The sides of the rectangles
    int leftA, leftB;
    int rightA, rightB;
    int topA, topB;
    int bottomA, bottomB;

    //Calculate the sides of rect A
    leftA = x1;
    rightA = x1 + w1;
    topA = y1;
    bottomA = y1 + h1;

    //Calculate the sides of rect B
    leftB = x2;
    rightB = x2 + w2;
    topB = y2;
    bottomB = y2 + h2;

    //If any of the sides from A are outside of B
    if( bottomA <= topB )
    {
        return false;
    }

    if( topA >= bottomB )
    {
        return false;
    }

    if( rightA <= leftB )
    {
        return false;
    }

    if( leftA >= rightB )
    {
        return false;
    }

    //If none of the sides from A are outside B
    return true;
}

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip, int alpha)
{
    //Holds offsets
    SDL_Rect offset;

    //Get offsets
    offset.x = x;
    offset.y = y;

    //Blit
    SDL_SetAlpha(source, SDL_SRCALPHA, alpha);
    SDL_BlitSurface( source, clip, destination, &offset );
}

SDL_Surface *load_image( std::string filename )
{
    SDL_Surface* loadedImage = NULL;
    SDL_Surface* optimizedImage = NULL;

    loadedImage = SDL_LoadBMP( filename.c_str() );

    if( loadedImage != NULL ){
        optimizedImage = SDL_DisplayFormat( loadedImage );
        SDL_FreeSurface( loadedImage );

        if( optimizedImage != NULL )
        {
            Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0xFF, 0, 0xFF );
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
        }
    }

    return optimizedImage;
}

void cleanup(){
    //SDL_FreeSurface( player );
    SDL_Quit();
}

int main( int argc, char* args[] )
{
    SDL_Init( SDL_INIT_EVERYTHING );
    screen = SDL_SetVideoMode( SCREENW, SCREENH, 32, SDL_SWSURFACE|SDL_FULLSCREEN);
    SDL_ShowCursor(SDL_DISABLE);
    //
	//

    BG = load_image( "gfx/bgnew.bmp" );//-192
    HUD = load_image( "gfx/hud/hud.bmp" );
    life = load_image( "gfx/hud/life.bmp" );
    power = load_image( "gfx/hud/power.bmp" );

    player = load_image( "gfx/p1.bmp" );
    for(int x = 0; x<9; x++){
                 for(int y = 0; y<2; y++){
                         int z = x+9*y+1;
                            pclip[z].x = x*PW;
                            pclip[z].y = y*PH;
                            pclip[z].w = PW;
                            pclip[z].h = PH;
                 }
     }

    tilesheet = load_image( "gfx/earth.bmp" );

    for(int x = 0; x<4; x++){
                 for(int y = 0; y<9; y++){
                         int z = x+4*y+1;
                            clip[z].x = x*TILEWIDTH;
                            clip[z].y = y*TILEHEIGHT;
                            clip[z].w = TILEWIDTH;
                            clip[z].h = TILEHEIGHT;
                 }
     }
     clip[4].h = 4*TILEHEIGHT;

    //orb = load_image( "gfx/orb.bmp" );

    Uint8 *keystates = SDL_GetKeyState( NULL );

    map.load("maps/testmap.map");
    p1.respawn();

    while(!quit) {
         SDL_PumpEvents();
         Uint8 *keystates = SDL_GetKeyState( NULL );
         if(keystates[SDLK_ESCAPE]) break;

         iter++;

         apply_surface(0,0,BG,screen);

         p1.move(keystates[SDLK_LEFT],keystates[SDLK_RIGHT],keystates[SDLK_SPACE]|keystates[SDLK_UP]);
         p1.collide(map.map);
         cam_x = p1.x-SCREENW/2;
         //cam_y = p1.y-SCREENH/2;
         cam_y = 0;
         if(cam_x<0)cam_x=0;
         if(cam_y<0)cam_y=0;
         if(cam_x-SCREENW>MAPWIDTH*TILEWIDTH)cam_x=MAPWIDTH*TILEWIDTH;
         //if(cam_y-SCREENH>MAPHEIGHT*TILEHEIGHT)cam_y=MAPHEIGHT*TILEHEIGHT;
         p1.draw();

         map.draw();

         apply_surface(0,0,HUD,screen);
         apply_surface(1,(p1.health-10)*-48+1-480,life,HUD);

         SDL_Flip( screen );
         SDL_FillRect(screen,NULL,0xffffff);
         SDL_Delay( WAITTIME  );
    }
    cleanup();
    return 0;
}
